﻿using Quartz;
using SBlogCore.Common.FriendlyException;
using SBlogCore.Entitys.SystemManager;

namespace SBlogCore.TaskJob
{
    public class OpenJobBuilder
    {
        private SysOpenJob? _job;
        private readonly IScheduler? _scheduler;

        private OpenJobBuilder(IScheduler scheduler)
        {
            this._scheduler = scheduler;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="scheduler"></param>
        /// <returns></returns>
        public static OpenJobBuilder Build(IScheduler scheduler)
        {
            return new OpenJobBuilder(scheduler);
        }

        /// <summary>
        /// 绑定Job
        /// </summary>
        /// <param name="job"></param>
        /// <returns></returns>
        public OpenJobBuilder BindJob(SysOpenJob job)
        {
            _job = job;
            return this;
        }
        /// <summary>
        /// 启动定时任务
        /// </summary>
        public async Task RunAsync(CancellationToken cancellationToken = default)
        {
            if (_scheduler==null)
                throw SBlogCoreException.Say("IScheduler不能为空！");
            if (_job == null)
                throw SBlogCoreException.Say("任务模型不存在，通过BindJob(),绑定任务模型。！");
            if (string.IsNullOrEmpty(_job.JobCall))
                throw SBlogCoreException.Say("任务地址不能为空！");
            var taskType = Type.GetType(_job.JobCall);
            if (taskType == null)
                throw SBlogCoreException.Say("任务地址不存在！");
            var jobBuilderType = typeof(JobBuilder);
            var method = jobBuilderType.GetMethods().FirstOrDefault(
                    x => x.Name.Equals("Create", StringComparison.OrdinalIgnoreCase) &&
                         x.IsGenericMethod && x.GetParameters().Length == 0)
                ?.MakeGenericMethod(taskType);
            if (method == null)
                throw SBlogCoreException.Say($"任务方法不存在！");
            var jobBuilder = (JobBuilder)method.Invoke(null, null);
            if (jobBuilder != null)
            {
                //WithIdentity:为定时任务设置名称
                IJobDetail jobDetail = jobBuilder.WithIdentity(_job.JobId).Build();
                jobDetail.JobDataMap["OpenJob"] = _job.JobId; //传递job信息
                ITrigger trigger = TriggerBuilder.Create()
                    .WithCronSchedule(_job.Cron)
                    .WithIdentity(_job.JobId)
                    .StartNow()
                    .Build();
              await _scheduler.ScheduleJob(jobDetail, trigger, cancellationToken);
            }
        }
        /// <summary>
        /// 停止一个定时任务
        /// </summary>
        public async Task StopAsync(CancellationToken cancellationToken=default)
        {
            if (_scheduler == null)
                throw SBlogCoreException.Say("IScheduler不能为空！");
            if (_job == null)
                throw SBlogCoreException.Say("任务模型不存在，通过BindJob(),绑定任务模型。！");
            TriggerKey triggerKey = new TriggerKey(_job.JobId);
            // 停止触发器
           await _scheduler.PauseTrigger(triggerKey, cancellationToken);
            // 移除触发器
           await _scheduler.UnscheduleJob(triggerKey, cancellationToken);
            // 删除任务
           await _scheduler.DeleteJob(new JobKey(_job.JobId), cancellationToken);
        }
    }
}
